using System;
using UnityEngine;

namespace Voodoo.Distribution
{
	public static class Localization
	{
		private const string _noLocalizationDatasetMessage = "No valid Localization dataset could be load.";

		private const string _keyDoesNotExistMessage = "Key: <color=cyan>{0}</color> doesn't exist.";

		public static string forcedLanguage;

		private static string _languageCode;

		private static string[] _languageCodes;

		private static string[] _translationKeys;

		private static LocalizationDebugger _debugger;

		private static LocalizationSet _set;

		public static LocalizationSet Set
		{
			get
			{
				if (_set != null)
				{
					return _set;
				}
				Mount();
				return _set;
			}
		}

		public static string[] LanguageCodes
		{
			get
			{
				if (_languageCodes != null)
				{
					return _languageCodes;
				}
				Mount();
				return _languageCodes;
			}
		}

		public static string[] TranslationKeys
		{
			get
			{
				if (_translationKeys != null)
				{
					return _translationKeys;
				}
				Mount();
				return _translationKeys;
			}
		}

		public static bool IsValid => Set != null;

		public static bool IsRightToLeftLanguage => LanguageCode == "HE";

		public static string LanguageCode => forcedLanguage ?? _languageCode;

		public static event Action languageChanged;

		static Localization()
		{
			_languageCode = "EN";
			LocalizationIO.sheetChanged += Mount;
			Initialize();
		}

		private static void Initialize()
		{
			Mount();
			if (_set == null)
			{
				Debug.LogError("No valid Localization dataset could be load.");
				return;
			}
			_languageCode = LocalizationLanguageCode.GetLanguageCode(Set);
			if (Application.isPlaying)
			{
				TranslateAll();
				if (Debug.isDebugBuild)
				{
					_debugger = new GameObject().AddComponent<LocalizationDebugger>();
				}
				Application.quitting += Dispose;
			}
		}

		public static void SetLanguage(string langCode)
		{
			_languageCode = langCode;
			TranslateAll();
		}

		public static void Dispose()
		{
			_set?.Dispose();
			_languageCodes = null;
			_translationKeys = null;
			Application.quitting -= Dispose;
		}

		private static void Mount()
		{
			LocalizationIO.SetupSheet(ref _languageCodes, ref _translationKeys, out _set);
		}

		public static string GetTranslation(string key, string languageCode = null, bool logError = true)
		{
			if (!KeyExist(key))
			{
				Debug.LogError($"Key: <color=cyan>{key}</color> doesn't exist.");
				return string.Empty;
			}
			if (_debugger != null && _debugger.longestStringModeEnabled)
			{
				return GetLongestString(key);
			}
			string key2 = languageCode ?? LanguageCode;
			return Set.languages[key2].translations[key];
		}

		public static bool KeyExist(string key)
		{
			for (int i = 0; i < TranslationKeys.Length; i++)
			{
				if (TranslationKeys[i] == key)
				{
					return true;
				}
			}
			return false;
		}

		private static string GetLongestString(string key)
		{
			int num = 0;
			string result = "";
			foreach (LanguageRegistry value in Set.languages.Values)
			{
				string text = value.translations[key];
				int roughLength = GetRoughLength(text);
				if (roughLength > num)
				{
					num = roughLength;
					result = text;
				}
			}
			return result;
		}

		private static int GetRoughLength(string word)
		{
			int num = 0;
			for (int i = 0; i < word.Length; i++)
			{
				switch (word[i])
				{
				case 'I':
				case 'i':
				case 'l':
					num++;
					break;
				case 'M':
				case 'W':
				case 'm':
				case 'w':
					num += 4;
					break;
				default:
					num += 2;
					break;
				}
			}
			return num;
		}

		public static void TranslateAll()
		{
			Translator[] array = UnityEngine.Object.FindObjectsOfType<Translator>();
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Translate();
			}
			Localization.languageChanged?.Invoke();
		}
	}
}
